home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume24 / faxpax / part02 < prev    next >
Encoding:
Internet Message Format  |  1991-03-12  |  54.5 KB

  1. Subject:  v24i040:  Email fax-sending package, Part02/05
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: 4beb9ab3 f356640f 2c0d96d7 a288ae7b
  5.  
  6. Submitted-by: klaus u schallhorn <cnix!klaus>
  7. Posting-number: Volume 24, Issue 40
  8. Archive-name: faxpax/part02
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then feed it
  12. # into a shell via "sh file" or similar.  To overwrite existing files,
  13. # type "sh file -c".
  14. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  15. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  16. # Contents:  FaxConfig faxhost/faxfonts/diykit.c faxhost/sendfax.c
  17. # Wrapped by rsalz@litchi.bbn.com on Wed Mar 13 14:08:01 1991
  18. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  19. echo If this archive is complete, you will see the following message:
  20. echo '          "shar: End of archive 2 (of 5)."'
  21. if test -f 'FaxConfig' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'FaxConfig'\"
  23. else
  24.   echo shar: Extracting \"'FaxConfig'\" \(25531 characters\)
  25.   sed "s/^X//" >'FaxConfig' <<'END_OF_FILE'
  26. X#!/bin/sh
  27. X#
  28. X# $Header: FaxConfig, 2.2.91, ks
  29. X# basically a [very much] stripped down and ripped off version of rn/Configure
  30. X# where it says:
  31. X# Yes, you may rip this off to use in other distribution packages.
  32. X# so I did
  33. X
  34. Xn=''
  35. Xc=''
  36. Xcontains=''
  37. X
  38. Xmodemtypes='1'
  39. X
  40. Xcharset='i'
  41. Xdevice="/dev/not_that_one"
  42. Xdevlock="LCK..nosuchdevice"
  43. Xdialstr=""
  44. Xdialtype='T'
  45. Xnet='y'
  46. Xnetwide_fax="NETWIDE_FAX"
  47. Xfaxhost="faxhost"
  48. Xfaxadmin=`whoami`
  49. Xfaxadmin="$faxadmin@"`hostname`
  50. Xfaxfmode='0644'
  51. Xfaxlib='/usr/local/lib/faxlib'
  52. Xfaxspool='/usr/local/spool/fax'
  53. Xfmtype="sierra"
  54. Xlocalbin='/usr/local/bin'
  55. Xloglevel='9'
  56. Xmanshelf='/usr/share/man'
  57. Xmaxresend='3'
  58. Xmaxage='1'
  59. Xmaxtry='5'
  60. Xtopspeed='7'
  61. Xuucplocks='/var/spool/locks'
  62. X
  63. X
  64. Xecho "Beginning of configuration questions for faxpak."
  65. Xecho " "
  66. X
  67. X: some greps do not return status, grrr.
  68. Xecho "grimblepritz" >grimble
  69. Xif grep blurfldyick grimble >/dev/null 2>&1 ; then
  70. X    contains=contains
  71. Xelse
  72. X    if grep grimblepritz grimble >/dev/null 2>&1 ; then
  73. X    contains=grep
  74. X    else
  75. X    contains=contains
  76. X    fi
  77. Xfi
  78. X
  79. X: sanity checks
  80. XPATH='.:/bin:/usr/bin:/usr/local/bin:/usr/ucb:/usr/local:/usr/lbin:/etc'
  81. Xexport PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh $0; kill $$)
  82. X
  83. Xif test ! -t 0; then
  84. X    echo "Type 'sh FaxConfig', not 'sh <FaxConfig'"
  85. X    exit 1
  86. Xfi
  87. X
  88. X: first determine how to suppress newline on echo command
  89. Xecho "Checking echo to see how to suppress newlines..."
  90. X(echo "hi there\c" ; echo " ") >.echotmp
  91. Xif $contains c .echotmp >/dev/null 2>&1 ; then
  92. X    echo "...using -n."
  93. X    n='-n'
  94. X    c=''
  95. Xelse
  96. X    echo "...using \\\c."
  97. X    n=''
  98. X    c='\c'
  99. Xfi
  100. Xecho $n "Type carriage return to continue.  Your cursor should be here-->$c"
  101. Xread ans
  102. Xrm .echotmp
  103. X
  104. X: now set up to do reads with possible shell escape
  105. X: if this does not work on your machine, 1,$s/. myread/read ans/
  106. Xcat <<EOSC >myread
  107. Xans='!'
  108. Xwhile expr "X\$ans" : "X!" >/dev/null; do
  109. X    read ans
  110. X    case "\$ans" in
  111. X    !)
  112. X    sh
  113. X    echo " "
  114. X    echo $n "Your answer: $c"
  115. X    ;;
  116. X    !*)
  117. X    set \`expr "X\$ans" : "X!\(.*\)\$"\`
  118. X    sh -c "\$*"
  119. X    echo " "
  120. X    echo $n "Your answer: $c"
  121. X    ;;
  122. X    esac
  123. Xdone
  124. XEOSC
  125. X
  126. X
  127. Xcat <<EOT
  128. X# general info
  129. X##############################################################################
  130. XThis installation shell script asks you some questions regarding the
  131. Xsetup of faxpak. Currently there is no support for hardware other than
  132. XSun Microsystems'. To port this to other machines run this script 
  133. Xanyway, but then have a close look at wiring.c. Wiring.c can be used
  134. Xas a standalone test program with TESTING defined, and with TEST_DEVICE
  135. Xdefined to a port you can use for testing [you can reconfig any time],
  136. Xpreferably without interfering logins.
  137. X
  138. XThis script builds a header file faxconfig.h, a soft configuration file
  139. Xfax,config, fax.1 man pages and, if you're lucky, two faxpak fonts.
  140. X
  141. XDefault answers are shown in [brackets]. Hitting carriage return accepts
  142. Xthe defaults. Once you have faxconfig.h and fax.config you can change
  143. Xeach file by editing it without re-running this script.
  144. X
  145. XEOT
  146. X
  147. Xecho $n "[Type carriage return to continue] $c"
  148. X. myread
  149. Xecho " "
  150. X
  151. X
  152. Xcat <<EOT
  153. X
  154. X##############################################################################
  155. Xfaxpak can run on networked and standalone machines.
  156. X
  157. XIf faxpak is networked, it is assumed that one HOST has the faxmodem[s],
  158. Xwith all other machines acting as CLIENTS, spooling outgoing fax jobs to
  159. Xthe faxhost.
  160. X
  161. XThe faxhosts' duty is to convert incoming text files into group 3 fax files,
  162. Xand to do the actual transmission, to log what's going on, to report by
  163. Xmail [if requested] and to do house keeping chores. This is done by entries
  164. Xin root's crontab which calls sendfax frequently and faxcleanup once a day.
  165. X
  166. XEOT
  167. X
  168. Xdflt=$net
  169. Xecho $n "Do you expect to run faxpak on networked machines? [$dflt] $c"
  170. X. myread
  171. Xecho
  172. Xcase $ans in
  173. X'') ans=$dflt;;
  174. Xesac
  175. X
  176. X
  177. Xif [ $ans = y ]
  178. Xthen
  179. X
  180. X    cat <<EOT
  181. X
  182. X# network info, don't really need much
  183. X######################################################################
  184. X"client" machines find the faxhost by calling gethostbyname(FAXHOST),
  185. Xwith FAXHOST #defined in faxconfig.h on our sita as "faxhost",
  186. Xand with "faxhost" aliased in /etc/hosts to mbox. mbox is a 3/60 that
  187. Xacts as our spooling machine [printing, faxing, mail, news archive etc.].
  188. X
  189. XEOT
  190. X
  191. X    dflt=$faxhost
  192. X    echo "Please enter the \"synonym\" your FAXHOST will be known by -"
  193. X    echo $n "[I guess you could enter the name of a known machine]: [$dflt] $c"
  194. X    . myread
  195. X    echo
  196. X    case $ans in
  197. X    '') ans=$dflt;;
  198. X    esac
  199. X    faxhost=$ans
  200. Xelse
  201. X    net='n'
  202. X    netwide_fax="nonet"
  203. Xfi
  204. X
  205. X
  206. Xcat <<EOT
  207. X
  208. X# we need someone to blame when things go wrong
  209. X##############################################################################
  210. XThe bad news is that things DO go wrong. Therefore we may need 
  211. Xsomeone to interfere by hand, or to lend a hand if a user needs help,
  212. Xor to give the default answer ["You can't to that"].
  213. X
  214. XEOT
  215. Xdflt=$faxadmin
  216. Xecho $n "Name a patient person suitable for dealing with fax problems: [$dflt] $c"
  217. X. myread
  218. Xecho
  219. Xcase $ans in
  220. X'') ans=$dflt;;
  221. Xesac
  222. Xfaxadmin=$ans
  223. X
  224. X
  225. X# what arg do we give chmod()
  226. X##############################################################################
  227. Xdflt=$faxfmode
  228. Xecho $n "Please enter the file access perms to be enforced by faxpak: [$dflt] $c"
  229. X. myread
  230. Xecho
  231. Xcase $ans in
  232. X'') ans=$dflt;;
  233. Xesac
  234. Xfaxfmode=$ans
  235. X
  236. Xcat <<EOT
  237. X
  238. X
  239. X# where to put faxlib and the spool dir
  240. X##############################################################################
  241. XTo keep things somewhat organised we need to define a /someplace/faxlib,
  242. Xand a /somewhere/spooldir for faxpak. I prefer to keep them separate from
  243. Xdistribution libs and spool dirs. I'd also like to know where you keep you
  244. Xman pages.
  245. X
  246. XEOT
  247. Xdflt=$faxlib
  248. Xecho $n "Please enter the path to faxlib: [$dflt] $c"
  249. X. myread
  250. Xecho
  251. Xcase $ans in
  252. X'') ans=$dflt;;
  253. Xesac
  254. Xfaxlib=$ans
  255. X
  256. X
  257. Xdflt=$faxspool
  258. Xecho $n "And path to faxspool: [$dflt] $c"
  259. X. myread
  260. Xecho
  261. Xcase $ans in
  262. X'') ans=$dflt;;
  263. Xesac
  264. Xfaxspool=$ans
  265. X
  266. X
  267. Xdflt=$manshelf
  268. Xecho $n "And your Manual Shelf: [$dflt] $c"
  269. X. myread
  270. Xecho
  271. Xcase $ans in
  272. X'') ans=$dflt;;
  273. Xesac
  274. Xmanshelf=$ans
  275. X
  276. Xcat <<EOT
  277. X
  278. X# find competing uucp locks
  279. X##############################################################################
  280. XModem logins, uucp transmissions and faxes all the same time and on
  281. Xthe same modem tend become somewhat garbled. Tell me where uucp keeps
  282. Xits lock files, so that sendfax dies away instantly if uucp is active
  283. X[it knows about logins on a port].
  284. X
  285. XEOT
  286. Xdflt=$uucplocks
  287. Xecho $n "Where does uucp create its lock files: [$dflt] $c"
  288. X. myread
  289. Xecho
  290. Xcase $ans in
  291. X'') ans=$dflt;;
  292. Xesac
  293. Xuucplocks=$ans
  294. X
  295. X
  296. Xcat <<EOT
  297. X
  298. X# local bin for fax
  299. X##############################################################################
  300. XAssuming you don't put local executables into /usr/{bin,ucb}, we need
  301. Xsort of a /local/bin to put the user interface [called fax] into.
  302. X
  303. XEOT
  304. Xdflt=$localbin
  305. Xecho $n "Where do you keep local executables: [$dflt] $c"
  306. X. myread
  307. Xecho
  308. Xcase $ans in
  309. X'') ans=$dflt;;
  310. Xesac
  311. Xlocalbin=$ans
  312. X
  313. X
  314. Xcat <<EOT
  315. X
  316. X# max no of resends within one transmission
  317. X##############################################################################
  318. XThe last hard wired bit of info is the number of resends. If a page is
  319. Xgarbled during transmission, the two hardware gizzmos, that is your
  320. Xfaxmodem on this side and the fax machine on the other end, can agree
  321. Xto resend that page. I don't know if fax machines have a built in limit
  322. Xfor the number of resent pages, I do, however, feel safer if I know
  323. Xsendfax doesn't spend all night resending a page. Having seen the different
  324. Xlevels of compliance to the CCITT specs, especially european fax machines',
  325. XI would doubt, if such a limit is enforced.
  326. X
  327. XEOT
  328. Xdflt=$maxresend
  329. Xecho $n "How often do you permit the resending of a page within one call [$dflt] $c"
  330. X. myread
  331. Xecho
  332. Xcase $ans in
  333. X'') ans=$dflt;;
  334. Xesac
  335. Xmaxresend=$ans
  336. X
  337. X
  338. X# have header info, get details for fax.config
  339. X##############################################################################
  340. X
  341. Xif [ $modemtypes = 2 ]
  342. Xthen
  343. X    mtypestring="faxmodem type, currently class2 and sierra type modems are supported"
  344. Xelse
  345. X    mtypestring="faxmodem type, currently only sierra type modems are supported"
  346. Xfi
  347. X
  348. Xcat <<EOT
  349. X
  350. X# soft configuration, saved in $faxlib/fax.config"
  351. X##############################################################################
  352. XMost of the configuration of faxpak can be changed after compiling faxpak.
  353. XSoftwired details are stashed into $faxlib/fax.config, allowing for easy 
  354. Xalteration once you have faxpak working. The fax.config file stores:
  355. X
  356. X1: the ports to which you have faxmodems connected *)
  357. X2: literal name of lockfile for each port, in case uucp uses these ports
  358. X   as well as faxpak *)
  359. X3: $mtypestring
  360. X4: Tone or Pulse dialling
  361. X5: Highest speed your faxmodems are capable of [RTFFaxmodemM]
  362. X6: an optinal string to re-enable dialins on the port after sendfax is done,
  363. X   see /etc/uucp/Dialers, or the modem docs, for examples
  364. X
  365. X7: wildcarded dialcodes and times, faxes to these area codes are ok *)
  366. X
  367. X8: max no of days a fax is allowed to sit in $faxspool
  368. X9: max no of attempts to send a fax
  369. X
  370. Xlog level, 9 logs everything [huge!], 0 only some relevant info
  371. X
  372. XFaxConfig only writes a preliminary file including some comments. Feel
  373. Xfree to edit it to your liking at any time.
  374. X
  375. X*) these are best done with an editor, in fact, I don't even ask for
  376. X   dialcode:time pairs. see the file fax.config when done with this script.
  377. X   [you could also call this load sharing between you and me].
  378. X
  379. XEOT
  380. X
  381. Xdflt=$device
  382. Xecho $n "Please enter the first port to be used [$dflt] $c"
  383. X. myread
  384. Xecho
  385. Xcase $ans in
  386. X'') ans=$dflt;;
  387. Xesac
  388. Xdevice=$ans
  389. X
  390. Xdflt=$devlock
  391. Xecho "Please enter lockname to block uucp while we're"
  392. Xecho $n "sending out faxes [$dflt] $c"
  393. X. myread
  394. Xecho
  395. Xcase $ans in
  396. X'') ans=$dflt;;
  397. Xesac
  398. Xdevlock=$ans
  399. X
  400. Xif [ $modemtypes = 2 ]
  401. Xthen
  402. X    dflt=$fmtype
  403. X    echo $n "Please enter modem type [$dflt] $c"
  404. X    . myread
  405. X    echo
  406. X    case $ans in
  407. X    '') ans=$dflt;;
  408. X    esac
  409. X    fmtype=$ans
  410. Xfi
  411. X
  412. Xdflt=$dialtype
  413. Xecho $n "Please enter 'P' if you want pulse dialling [$dflt] $c"
  414. X. myread
  415. Xecho
  416. Xcase $ans in
  417. X'') ans=$dflt;;
  418. Xesac
  419. Xdialtype=$ans
  420. X
  421. Xdflt=$topspeed
  422. Xecho "Please enter code for highest baud rate your modem can "
  423. Xecho $n "fax at - see modem manual [$dflt] $c"
  424. X. myread
  425. Xecho
  426. Xcase $ans in
  427. X'') ans=$dflt;;
  428. Xesac
  429. Xtopspeed=$ans
  430. X
  431. Xdflt=$dialstring
  432. Xecho "If you feel brave enough [else leave blank and do later]"
  433. Xecho $n "String to reenable dialins on ports used by faxmodems [$dflt] $c"
  434. X. myread
  435. Xecho
  436. X
  437. Xdflt=$maxage
  438. Xecho $n "How many days is a fax allowed to sit in the queue [$dflt] $c"
  439. X. myread
  440. Xecho
  441. Xcase $ans in
  442. X'') ans=$dflt;;
  443. Xesac
  444. Xmaxage=$ans
  445. X
  446. Xdflt=$maxage
  447. Xecho $n "How many attempts do you allow to connect to one phone no [$dflt] $c"
  448. X. myread
  449. Xecho
  450. Xcase $ans in
  451. X'') ans=$dflt;;
  452. Xesac
  453. Xmaxtry=$ans
  454. X
  455. Xdflt=$loglevel
  456. Xecho $n "What log level do you want sendfax [wiring for testing] to log at [$dflt] $c"
  457. X. myread
  458. Xecho
  459. Xcase $ans in
  460. X'') ans=$dflt;;
  461. Xesac
  462. Xloglevel=$ans
  463. X
  464. X
  465. X
  466. Xcat <<EOT
  467. X
  468. X# charset info
  469. X##############################################################################
  470. XAlthough I planned to support quite a few different character sets [with
  471. Xthe help of several netters] faxpak currently supports the following few. 
  472. XFor those poor souls whose expression is limited to 7 bits, the decision
  473. Xmust be based on rand().
  474. X
  475. XPlease enter the charset you want faxpak to use:
  476. X
  477. X    i    iso 8859.1
  478. X    p    pc de facto [code page 850] standard *)
  479. X    8    pc code page 861
  480. X
  481. X*) Some people felt strongly the ibm pc code page 850 is NOT a de facto
  482. X   standard. IMHO it is insofar as the uk, germany, switzerland and some
  483. X   other mid european countries are concerned, where quite a chunk of 
  484. X   "the action" takes place. If you still disagree, don't use faxpak.
  485. X
  486. XEOT
  487. X
  488. Xdflt=$charset
  489. Xecho $n "What charset do you want to use [$dflt] $c"
  490. X. myread
  491. Xecho
  492. Xecho    copying font definition for diy font kit
  493. Xcase $ans in
  494. X'p')    cp faxhost/faxfonts/diy_ibmpc.def faxhost/faxfonts/diykit.def;;
  495. X'8')    cp faxhost/faxfonts/diy_codep861.def faxhost/faxfonts/diykit.def;;
  496. X*)    cp faxhost/faxfonts/diy_iso.def faxhost/faxfonts/diykit.def;;
  497. Xesac
  498. X
  499. Xrm -f myread grimble
  500. X
  501. X
  502. X# have fax.config, write faxconfig.h and fax.config
  503. X###################################################
  504. X
  505. Xecho    "writing faxconfig.h"
  506. X
  507. Xcat    >faxconfig.h <<EOT
  508. X
  509. X/*
  510. X    fax configuration header [faxconfig.h],
  511. X    shared by faxclient/fax.c, and faxhost/*.c
  512. X
  513. X    Copyright (C) 1991, klaus schallhorn, klaus@cnix.uucp
  514. X
  515. X    Permission to use, copy, modify, and distribute this software 
  516. X    and its documentation for any purpose and without fee is hereby 
  517. X    granted, provided that the above copyright notice appear in 
  518. X    all copies and that both that copyright notice and this permission 
  519. X    notice appear in supporting documentation. 
  520. X
  521. X    This software is provided "as is" without express or implied warranty.
  522. X*/
  523. X
  524. X#define    $netwide_fax
  525. X
  526. X
  527. X            /* some common bits 'n pieces */
  528. X#ifndef    TRUE
  529. X#define    TRUE        1
  530. X#define    FALSE        0
  531. X#define    ERROR        (-1)
  532. X#endif
  533. X
  534. X#ifndef    min
  535. X#define    min(a,b)    ((a<b)?a:b)
  536. X#define    max(a,b)    ((a>b)?a:b)
  537. X#endif
  538. X
  539. X
  540. X            /* network stuff */
  541. X#ifdef    NETWIDE_FAX
  542. X#define    FAXHOST        "$faxhost"        /* get host by name */
  543. X#endif
  544. X
  545. X
  546. X            /* application specific stuff */
  547. X#define    FAXADMIN    "$faxadmin"        /* mail errors if !user */
  548. X#define    FAXFMODE    $faxfmode            /* for chmod */
  549. X#define    FAXSERVER    "spool.fax"        /* name of spool pgm */
  550. X#define    FAXLIB        "$faxlib"    /* needed on faxhost only */
  551. X#define    FAXSPOOL    "$faxspool"    /* needed on faxhost only */
  552. X
  553. X#define    UUCPLOCKS    "$uucplocks"    /* again host only */
  554. X#define    LOCALBIN    "$localbin"        /* client && host, for fax.c */
  555. X
  556. X#define    MAX_RESEND    $maxresend            /* don't resend a page forever */
  557. X#define    FAXLFONT    "textfaxl.font"        /* lores bitmap font from diykit */
  558. X#define    FAXHFONT    "textfaxh.font"        /* hires bitmap font from diykit */
  559. X#define    PSFONT        "Courier-Bold12"    /* ghostscript font */
  560. X
  561. X#define    MAX_FAX_LINES    2400        /* is a bit generous, so what */
  562. X
  563. X#define    COARSE        1        /* 204.15 by 97.79 dpi */
  564. X#define    FINE        2        /* 204.15 by 195.58 dpi */
  565. X#define    HP        3
  566. X
  567. X#define    ASCII        0    /* use hp laser jet compat font to create pbm */
  568. X#define    PBM        1    /* use as is, sort of */
  569. X            /* these aren't done yet, see wiring.c, why */
  570. X#define    DVI        2    /* dvi2ps, NOT YET DONE */
  571. X#define    GHOSTSCRIPT    3    /* ideas [not yet] stolen from mit ai labs */
  572. X#define    HPCL        4    /* hp laser jet compat output */
  573. X
  574. X
  575. X            /* fax modem specific bits */
  576. X#define    BETA_FIRMWARE        /* applies to wiring.c */
  577. X#define    SIERRA            /* type of fax modem */
  578. X
  579. X
  580. X#ifdef    NEED_FAXTYPES        /* needed in fax.c and spool.fax.c */
  581. Xstruct    ftypes
  582. X{
  583. X    char    *typename;
  584. X    int    typeid;
  585. X} faxtypes[] =
  586. X{
  587. X    "ascii",    ASCII,
  588. X    "pbm",        PBM,
  589. X    "dvi",        DVI,
  590. X    "postscript",    GHOSTSCRIPT,
  591. X    "hpcl"        HPCL
  592. X};
  593. X#define    MAX_FTYPE    sizeof(faxtypes)/sizeof(struct ftypes)
  594. X#endif    /* need fax types */
  595. X
  596. X
  597. Xstruct FAX
  598. X{
  599. X    long    spooled;
  600. X    char    user[80];
  601. X#ifdef    JOBID
  602. X    char    jobid[80];
  603. X#endif
  604. X    char    dname[256];
  605. X    char    xname[256];
  606. X    char    **phone;
  607. X    int    tries,
  608. X        hires,
  609. X        uid,
  610. X        now,
  611. X        mail,
  612. X        pages,
  613. X        type,
  614. X        phone_nos;
  615. X    long    tpos,
  616. X        ppos;
  617. X};
  618. XEOT
  619. X
  620. Xecho    "writing fax.config"
  621. X
  622. Xcat    >fax.config <<EOT
  623. X# fax.config
  624. X# Copyright (C) 1991 klaus schallhorn, klaus@cnix.uucp
  625. X#
  626. X# Permission to use, copy, modify, and distribute this software 
  627. X# and its documentation for any purpose and without fee is hereby 
  628. X# granted, provided that the above copyright notice appear in 
  629. X# all copies and that both that copyright notice and this permission 
  630. X# notice appear in supporting documentation. 
  631. X#
  632. X# This software is provided "as is" without express or implied warranty.
  633. X#
  634. X#
  635. X# fax devices
  636. X# ===========
  637. X# 2nd column contains the actual device for sendfax
  638. X# ie /dev/cua1
  639. X#
  640. X# 3rd col states lock name to be used so that uucp does not even try 
  641. X# to interfere while we're faxing. Stating the lock name verbatim is 
  642. X# essential since there are differences between HDB uucp and older/other 
  643. X# versions.
  644. X# NOTE: if you don't share faxmodems with uucp, locknames don't really 
  645. X# matter as long as each port has a distinctive lockname. fred1, fred2 
  646. X# ... fredn would be acceptable.
  647. X#
  648. X# 4th col specifies the modem type connected to that port so sendfax knows 
  649. X# how to talk to the hardware.
  650. X#
  651. X# 5th col is either T [as in tone dialling] or P [pulse].
  652. X#
  653. X# 6th col is highest speed you want to connect at, see your modem manual.
  654. X#
  655. X# 7th col is a string sent to the fax modem AFTER we've used it IF you 
  656. X# want to enable incoming calls/getty, for a typical string see 
  657. X# /etc/uucp/Diallers, string has to be "in quotes", absence of a string 
  658. X# implies nothing to send.
  659. X#
  660. X# this is what fax.config looks here
  661. X# 1st    2nd        3rd            4th      5th 6th 7th
  662. X#device    /dev/cua1   LCK..cua1   sierra     T   7 "ATE1M0V1X1Q0S2=127S0=4S12=255"
  663. X#device    /dev/cua2   LCK..cua2   sierra     T   7 "ATE1M0V1X1Q0S2=127S0=4S12=255"
  664. Xdevice    $device    $devlock    $fmtype    $dialtype    $topspeed    $dialstr
  665. X#
  666. X#
  667. X# phone bill saver
  668. X# ================
  669. X#
  670. X# I do not want faxes at peak rates, except local ones.
  671. X#
  672. X# long distance call phone nos start with a zero PLUS any combination of 
  673. X# digits 1 to 9 [1-9][1-9]* 
  674. X# NOTE: no zeros in 2nd or 3rd digit, except if 2nd digit > 1
  675. X#
  676. X# international ones start with 010 cty code PLUS any combination of 1 to 9
  677. X#
  678. X# This feature can be raped to make sure faxes to specific fax numbers 
  679. X# are only sent at an acceptable [for the recipient] time, as shown in the 
  680. X# first "hour entry". Hard coded phone nos should come before wild card 
  681. X# entries.
  682. X#
  683. X# This sample states that long distance is ok from 6 pm to 6 am, 
  684. X# international ones from 8 pm to 6 am
  685. X#
  686. X#hours    0104977777777    9 - 12    # this guy can only be sent to in the morning
  687. X#hours    01049123456    8 - 10 14 16 - 19 
  688. X#hours    0[1-9][1-9]*    18 - 6    # as in 078 123 6789
  689. X#hours    0[2-9]*        18 - 6    # as in 030 455 6748
  690. X#hours    010[1-9]*    20 - 6    # as in 01049 30 345 6789
  691. X#
  692. X#
  693. X# max age of files in spool dir [days], fax is supposed to be fast!
  694. X# =============================
  695. X#
  696. Xmaxage    $maxage
  697. X#
  698. X#
  699. X# max number of attempts to connect
  700. X# =================================
  701. X#
  702. Xmaxtry    $maxtry
  703. X#
  704. X# log level
  705. X# =========
  706. X#
  707. X# 9 = everything
  708. X# 0 = errors, transmission times
  709. X# other useful levels are 3 and 5
  710. X#
  711. Xloglevel $loglevel
  712. X#
  713. X#
  714. X# end of fax.config
  715. XEOT
  716. X
  717. X# now save fax.1 man pages
  718. X##########################
  719. X
  720. Xecho    "writing faxclient/fax.1 man pages"
  721. X
  722. Xcat    >faxclient/fax.1 <<EOT
  723. X.TH fax 1 "Feb 4th, 1991"
  724. X.SH NAME
  725. Xfax \- send a Group 3 fax via faxmodem.
  726. X.SH SYNOPSIS
  727. Xfax phone_no [-a -f -h -l -m -n -r -s] file
  728. X.SH DESCRIPTION
  729. XFax accepts ascii input and sends it as a group 3 fax
  730. Xusing a sierra type faxmodem. The first parameter is either
  731. Xa phone number, an alias [see aliases] or a distribution list [see lists] 
  732. Xfile name.
  733. X.sp
  734. XIf the first parameter contains digits only, it is
  735. Xassumed to be a phone number.
  736. X.sp
  737. XIf your site does enforce permissions, you may have to ask your
  738. Xadministrator [$faxadmin] for permission to fax.
  739. X.SH PARAMETERS
  740. X.TP
  741. X.B -a'for the attention of...'
  742. XTo specify a recipient within an organization for internal
  743. Xrouting. The string must be quoted so it's passed as one
  744. Xargument to fax. It is then prepended to the outgoing message.
  745. X.TP
  746. X.B -f/absolute/font/path/fontfile
  747. XUse an alternative font. In addition to the default typewriter fonts
  748. Xin low and high resolution fax knows about 
  749. XHP Laserjet compatible fonts [up to 30 points in height]. These are
  750. Xscaled to the resolution of the outgoing fax. Used with low resolution
  751. Xthe output is not pretty.
  752. X.TP
  753. X.B -h
  754. XUse high resolution mode [204 by 195 dots per inch]. This almost doubles
  755. Xthe transmission time.
  756. X.TP
  757. X.B -l
  758. XUse low resolution mode [204 by 97 dots per inch].
  759. X.TP
  760. X.B -m
  761. XReport by mail as soon as the fax has been sent. Fatal errors or failure
  762. Xto deliver is reported back irrespectible of the mail flag setting.
  763. X.TP
  764. X.B -n
  765. XSend the fax "now" rather than at cheap rate, where "now" refers
  766. Xto the next time the fax daemon runs. To bypass the time restrictions [if
  767. Xany] you may need to have special permission.
  768. X.TP
  769. X.B -r'return fax number string'
  770. XThis string is prepended to the outgoing fax to specify a return
  771. Xfax number. Currently fax does not support incoming faxes.
  772. X.TP
  773. X.B -s
  774. XSave outgoing faxes in HOME/Fax.Sent/phone.date. Fax saves outgoing faxes in
  775. Xfiles whose name is a concatenation of recipient and date. If the recipient
  776. Xis not an alias and not a distribution list, the phone number is
  777. Xused for the first part of the file name.
  778. X.PP
  779. XFile is an ascii file containing a formatted message.
  780. X.SH DEFAULTS
  781. XYou can override built in defaults by creating a file ".faxrc" in
  782. Xyour home directory. This file is consulted before fax reads 
  783. Xcommand line parameters.
  784. X.sp
  785. XPermitted default values in .faxrc are those that apply to
  786. Xall outgoing faxes sent by one user. Command line option override
  787. Xthese dafaults, however.
  788. X.TP
  789. X.B font
  790. XThe name of a font to be used by fax. The font has to be available
  791. Xon the machine running the fax daemon. The fontfile
  792. Xmust be accessible to the fax daemon.
  793. X.TP
  794. X.B resolution
  795. XCan be high or low [see above]. Default: low. 
  796. X.TP
  797. X.B mail
  798. XSet to yes for notification by mail. Default: no.
  799. X.TP
  800. X.B now
  801. XSet to yes for sending next time the fax queue is checked
  802. Xfor outgoing faxes. Default: no.
  803. X.TP
  804. X.B retfax
  805. XA string to be prepended all your outgoing faxes. No default string.
  806. X.TP
  807. X.B save
  808. XIf set, saves files in HOME/Fax.Sent/phone.date. Default: no.
  809. X.SH ALIASES
  810. XIf the first parameter to fax contains alphabetic characters, fax first
  811. Xchecks your HOME directory for a file fax.aliases. This file contains
  812. Xa list of names, phone numbers, optionally ftao [for the attention of] 
  813. Xstrings to be prepended to each outgoing fax. Anything appearing after a # 
  814. Xsign is treated as a comment.
  815. X.sp
  816. XA sample fax.aliases file might look:
  817. X.sp
  818. X.nf
  819. Xfred    12345678    :For the attn of Fred Bloggs     # comment
  820. Xbill    98765
  821. Xsue    765432389    :The Lady in Pink             # another comment
  822. X.fi
  823. X.SH LISTS
  824. XIf an alias is not found in fax.aliases, fax tries to open a distribution
  825. Xlist with the same name. Distribution lists are similar to alias files.
  826. XA sample distribution list might look:
  827. X.sp
  828. X.nf
  829. X12345678    :For the attn of Fred Bloggs     # comment
  830. X98765
  831. X765432389    :The Lady in Pink             # another comment
  832. X.fi
  833. X.SH INTERACTIVE USE
  834. XIf fax is not given a file name on the command line, it reads 
  835. Xit's standard input until a line starting with a '.' is encountered,
  836. Xor until EOF.
  837. X.sp
  838. XEntering of a fax can be aborted by hitting ^C. Entering ~v at the beginning of
  839. Xa line calls the default editor, if specified by the environment variable
  840. XEDITOR, or /usr/ucb/vi.
  841. X.sp
  842. XStarting a line with ~p prints the message entered to far.
  843. X.SH AUTHOR
  844. XKlaus Schallhorn
  845. X.SH COPYRIGHT
  846. XCopyright (C) 1991 Klaus Schallhorn, klaus@cnix.uucp
  847. X.sp
  848. XPermission to use, copy, modify, and distribute this software and its
  849. Xdocumentation for any purpose and without fee is hereby granted, provided
  850. Xthat the above copyright notice appear in all copies and that both that
  851. Xcopyright notice and this permission notice appear in supporting
  852. Xdocumentation.  This software is provided "as is" without express or
  853. Ximplied warranty.
  854. XEOT
  855. X
  856. Xecho    "writing Makefiles"
  857. X
  858. Xcat    >Makefile <<EOT
  859. X# Makefile for faxpak
  860. X#
  861. X# Copyright (C) 1991 klaus schallhorn, klaus@cnix.uucp
  862. X#
  863. XCC =        cc
  864. XCFLAGS =    -O2
  865. XLDFLAGS =    -s
  866. X
  867. XFAXLIB =    $faxlib
  868. XFAXFMODE =    $faxfmode
  869. XLOCALBIN =    $localbin
  870. XMANSHELF =    $manshelf
  871. X
  872. XSHELL =        /bin/sh
  873. X
  874. XSUBS =        faxclient faxhost faxhost/faxfonts
  875. X
  876. X
  877. Xall:
  878. X    for i in \$(SUBS) ; do \
  879. X        ( cd \$\$i ; make \$(MFLAGS) 'CC=\$(CC)' 'CFLAGS=\$(CFLAGS)' 'LDFLAGS=\$(LDFLAGS)' all ); \
  880. X    done
  881. X
  882. Xinstall:
  883. X    for i in \$(SUBS) ; do \
  884. X        ( cd \$\$i ; make \$(MFLAGS) 'LOCALBIN=\$(LOCALBIN)' 'MANSHELF=\$(MANSHELF)' 'FAXLIB=\$(FAXLIB)' 'FAXFMODE=\$(FAXFMODE)' install ); \
  885. X    done
  886. X
  887. Xclean:
  888. X    -rm -f Part?? *.hdr fax.config
  889. X    for i in \$(SUBS) ; do \
  890. X        ( cd \$\$i ; make \$(MFLAGS) clean ); \
  891. X    done
  892. X
  893. XEOT
  894. X
  895. Xcat    >faxclient/Makefile <<EOT
  896. X# Makefile for faxclient
  897. X
  898. Xall:        fax
  899. X
  900. Xfax:        fax.o
  901. X        cc -o fax \$(LDFLAGS) fax.o
  902. X
  903. Xfax.o:        fax.c
  904. X        cc \$(CFLAGS) -c fax.c
  905. X
  906. Xinstall:    bininstall maninstall
  907. X
  908. Xbininstall:    fax
  909. X        cp fax \$(LOCALBIN)
  910. X
  911. Xmaninstall:    fax.1
  912. X        cp fax.1 \$(MANSHELF)/man1
  913. X        chmod 644 \$(MANSHELF)/man1/fax.1
  914. Xclean:
  915. X        -rm -f *.o *.a core fax
  916. X
  917. XEOT
  918. X
  919. Xcat    >faxhost/Makefile <<EOT
  920. X# Makefile for faxhost
  921. X
  922. XFAXCLEANUP =    faxcleanup.o faxlog.o
  923. XSENDFAX =    sendfax.o wiring.o faxlog.o
  924. XSPOOLFAX =    spool.fax.o faxlog.o
  925. XTEXTTOPBM =    texttopbm.o fntwrite.o
  926. XFAXHDR =    ../faxconfig.h
  927. X
  928. XPGMS =        faxcleanup sendfax spool.fax texttopbm
  929. XTEXTFILES =    fax.config textfaxl.font textfaxh.font
  930. X
  931. Xall:        \$(PGMS)
  932. X
  933. Xfaxcleanup:    \$(FAXHDR) \$(FAXCLEANUP)
  934. X        cc -o faxcleanup \$(LDFLAGS) \$(FAXCLEANUP)
  935. X
  936. Xsendfax:    \$(FAXHDR) sierracmd.h \$(SENDFAX)
  937. X        cc -o sendfax \$(LDFLAGS) \$(SENDFAX)
  938. X
  939. Xspool.fax:    \$(FAXHDR) \$(SPOOLFAX)
  940. X        cc -o spool.fax \$(LDFLAGS) \$(SPOOLFAX)
  941. X
  942. Xtexttopbm:    \$(FAXHDR) \$(TEXTTOPBM)
  943. X        cc -o texttopbm \$(LDFLAGS) \$(TEXTTOPBM)
  944. X
  945. Xinstall:
  946. X        cp \$(PGMS) \$(FAXLIB)
  947. X        cp ../fax.config \$(FAXLIB)
  948. X        for i in \$(TEXTFILES) ; do \
  949. X            ( chmod \$(FAXFMODE) \$(FAXLIB)/\$\$i ); \
  950. X        done
  951. X        for i in \$(PGMS) ; do \
  952. X            ( chmod 0500 \$(FAXLIB)/\$\$i ); \
  953. X        done
  954. X        chmod 6711 \$(FAXLIB)/spool.fax
  955. X        chown root.daemon \$(FAXLIB)/*
  956. X
  957. Xclean:
  958. X        -rm -f *.o *.a core \$(PGMS)
  959. X
  960. XEOT
  961. X
  962. Xcat    >faxhost/faxfonts/Makefile <<EOT
  963. X# Makefile for faxhost/faxfonts
  964. X
  965. X# path for textfax?.font is hardwired into diykit [in ../../faxconfig.h]
  966. Xall:        diykit lores.data hires.data \
  967. X            $faxlib/textfaxl.font $faxlib/textfaxh.font
  968. X
  969. Xdiykit:        diykit.o
  970. X        cc -o diykit \$(LDFLAGS) diykit.o
  971. X
  972. Xdiykit.o:    ../../faxconfig.h diykit.h diykit.c
  973. X        cc \$(CFLAGS) -c diykit.c
  974. X
  975. X# path for textfax?.font is hardwired into diykit [in ../../faxconfig.h]
  976. X$faxlib/textfaxl.font: lores.data
  977. X        ./diykit
  978. X
  979. X$faxlib/textfaxh.font: hires.data
  980. X        ./diykit
  981. X
  982. Xlores.data:    lores.uue
  983. X        uudecode lores.uue && uncompress lores.data.Z
  984. X
  985. Xhires.data:    hires.uue
  986. X        uudecode hires.uue && uncompress hires.data.Z
  987. X
  988. X
  989. Xinstall:
  990. X
  991. Xclean:
  992. X        -rm -f *.o *.a *.data core diykit
  993. X
  994. XEOT
  995. X
  996. X# end of FaxConfig
  997. END_OF_FILE
  998.   if test 25531 -ne `wc -c <'FaxConfig'`; then
  999.     echo shar: \"'FaxConfig'\" unpacked with wrong size!
  1000.   fi
  1001.   # end of 'FaxConfig'
  1002. fi
  1003. if test -f 'faxhost/faxfonts/diykit.c' -a "${1}" != "-c" ; then 
  1004.   echo shar: Will not clobber existing file \"'faxhost/faxfonts/diykit.c'\"
  1005. else
  1006.   echo shar: Extracting \"'faxhost/faxfonts/diykit.c'\" \(5399 characters\)
  1007.   sed "s/^X//" >'faxhost/faxfonts/diykit.c' <<'END_OF_FILE'
  1008. X#include <stdio.h>
  1009. X#include <malloc.h>
  1010. X#include <ctype.h>
  1011. X#include "diykit.h"
  1012. X
  1013. X#include "../../faxconfig.h"
  1014. X
  1015. Xstatic    char *PGM = "diykit";
  1016. Xchar    charset[128];
  1017. Xint    bm_len;
  1018. Xextern    int errno;
  1019. X
  1020. Xstruct    FNT_BITMAP    /* one for each char */
  1021. X{
  1022. X    short *SH;
  1023. X    short active;
  1024. X} font[256];
  1025. X
  1026. X
  1027. Xfont_init(name)
  1028. Xchar *name;
  1029. X{
  1030. X    FILE *hp;
  1031. X    int i;
  1032. X    struct FNT_BITMAP *cf;
  1033. X    static int fst;
  1034. X    char tmp[4];
  1035. X
  1036. X    errno = 0;
  1037. X    if (!fst)
  1038. X        for (i=0; i<256; i++)    /* just to be safe */
  1039. X        {
  1040. X            cf = &font[i];
  1041. X            cf->SH = (short *)NULL;
  1042. X            cf->active = 0;
  1043. X        }
  1044. X    else for (i=0; i<256; i++)    /* just to be safe */
  1045. X        {
  1046. X            cf = &font[i];
  1047. X            if (cf->SH)
  1048. X                free(cf->SH);
  1049. X            cf->SH = (short *)NULL;
  1050. X            cf->active = 0;
  1051. X        }
  1052. X
  1053. X    if ((hp = fopen(name, "r")) == NULL)
  1054. X    {
  1055. X        fprintf(stderr,"%s: can't open %s font, errno %d\n",PGM,name,errno);
  1056. X        return(ERROR);
  1057. X    }
  1058. X
  1059. X    if (fread(tmp, sizeof(char), 3, hp) != 3)
  1060. X    {
  1061. X        fprintf(stderr,"%s: can't read fontfile %s, errno %d\n",PGM,name,errno);
  1062. X        return(ERROR);
  1063. X    }
  1064. X    if (!strncmp(tmp, "fxL", 3))
  1065. X        bm_len = 16;
  1066. X    else if (!strncmp(tmp, "fxH", 3))
  1067. X        bm_len = 32;
  1068. X    else
  1069. X    {
  1070. X        fprintf(stderr,"%s: %s is not a bitmap font\n",PGM,name);
  1071. X        return(ERROR);
  1072. X    }
  1073. X
  1074. X    if (rd_diykit(hp))
  1075. X        return(ERROR);
  1076. X
  1077. X    fclose(hp);
  1078. X    ++fst;
  1079. X    return(0);
  1080. X}
  1081. Xrd_diykit(fp)
  1082. XFILE *fp;
  1083. X{
  1084. X    int i, lastc;
  1085. X    struct FNT_BITMAP *cf;
  1086. X    short cur_char;
  1087. X    char curchar[8];
  1088. X
  1089. X    for (cur_char=0;;)
  1090. X    {
  1091. X        lastc = cur_char;
  1092. X            /* not all machines are big endian ones */
  1093. X            /* diykit therefore stores cur_char as a */
  1094. X            /* 4 byte ascii string. It is, however written */
  1095. X            /* as a short. */
  1096. X        if ((i = fread(curchar, 4, 1, fp)) != 1)
  1097. X        {
  1098. X            if (cur_char > 0x7e && (!i))
  1099. X                break;
  1100. X            fprintf(stderr,"%s: read error %d in font\n",PGM,errno);
  1101. X            return(ERROR);
  1102. X        }
  1103. X        curchar[4] = '\0';
  1104. X        cur_char = (short)atoi(curchar);
  1105. X        if (cur_char <= 0x20 || cur_char > 0xff)
  1106. X        {
  1107. X            fprintf(stderr,"%s: illegal curchar value %04x after char %3d\n",
  1108. X                PGM,cur_char,lastc);
  1109. X            return(ERROR);
  1110. X        }
  1111. X        cf = &font[cur_char];
  1112. X
  1113. X        if ((cf->SH = (short *)malloc(bm_len * sizeof(short))) == (short *)NULL)
  1114. X        {
  1115. X            fprintf(stderr,"%s: not enough memory for bitmap array char %d\n",
  1116. X                PGM,cur_char);
  1117. X            return(ERROR);
  1118. X        }
  1119. X
  1120. X        if (fread(cf->SH, sizeof(short), bm_len, fp) != bm_len)
  1121. X        {
  1122. X            fprintf(stderr,"%s: read error %d for char bitmap %d\n",
  1123. X                PGM,errno,cur_char);
  1124. X            return(ERROR);
  1125. X        }
  1126. X        cf->active = TRUE;
  1127. X    }
  1128. X    return(0);
  1129. X}
  1130. Xwritekit(hp,kit)
  1131. XFILE *hp, *kit;
  1132. X{
  1133. X    struct FNT_BITMAP *cf;
  1134. X    short cur_char, i, pos;
  1135. X    char tmp[4];
  1136. X
  1137. X    if (bm_len == 16)
  1138. X        strcpy(tmp, "fxL");
  1139. X    else strcpy(tmp, "fxH");
  1140. X
  1141. X    if (fwrite(tmp, sizeof(char), 3, hp) != 3)
  1142. X    {
  1143. X        fprintf(stderr,"%s: write error %d on fontfile\n",PGM,errno);
  1144. X        return(ERROR);
  1145. X    }
  1146. X
  1147. X    for (cur_char=33; cur_char<128; cur_char++)
  1148. X    {
  1149. X        cf = &font[cur_char];
  1150. X        if (cf->active)
  1151. X        {
  1152. X            if (fwrite(&cur_char, sizeof(short), 1, hp) != 1)
  1153. X            {
  1154. X                fprintf(stderr,"%s: write error %d on font\n",
  1155. X                    PGM,errno);
  1156. X                return(ERROR);
  1157. X            }
  1158. X            if (fwrite(cf->SH, sizeof(short), bm_len, hp) != bm_len)
  1159. X            {
  1160. X                fprintf(stderr,"%s: write error %d on font\n",
  1161. X                    PGM,errno);
  1162. X                return(ERROR);
  1163. X            }
  1164. X        }
  1165. X    }
  1166. X
  1167. X    while ((cur_char = getnext_char(&pos,kit)) != EOF)
  1168. X    {
  1169. X        cf = &font[cur_char];
  1170. X        if (cf->active)
  1171. X        {
  1172. X            if (fwrite(&pos, sizeof(short), 1, hp) != 1)
  1173. X            {
  1174. X                fprintf(stderr,"%s: write error %d on font\n",
  1175. X                    PGM,errno);
  1176. X                return(ERROR);
  1177. X            }
  1178. X            if (fwrite(cf->SH, sizeof(short), bm_len, hp) != bm_len)
  1179. X            {
  1180. X                fprintf(stderr,"%s: write error %d on font\n",
  1181. X                    PGM,errno);
  1182. X                return(ERROR);
  1183. X            }
  1184. X        }
  1185. X    }
  1186. X    return(0);
  1187. X}
  1188. Xgetnext_char(pos,fp)
  1189. Xshort *pos;
  1190. XFILE *fp;
  1191. X{
  1192. X    char buf[128], charname[40];
  1193. X    int found, Pos;
  1194. X    static int line;
  1195. X
  1196. X    for (;;)
  1197. X    {
  1198. X        if (fgets(buf, 126, fp) == NULL)
  1199. X            return(EOF);
  1200. X        ++line;
  1201. X        if (buf[0] != '#')
  1202. X        {
  1203. X            if (sscanf(buf,"%d %s",&Pos,charname) < 2)
  1204. X            {
  1205. X                fprintf(stderr,"%s: def file looks wrong to me at line %d\n",PGM,line);
  1206. X                return(EOF);
  1207. X            }
  1208. X            *pos = Pos;
  1209. X            if ((found = find_def(charname)) == EOF)
  1210. X            {
  1211. X                fprintf(stderr,"%s: unknown char def {%s} at at line %d\n",
  1212. X                    PGM,charname,line);
  1213. X                return(EOF);
  1214. X            }
  1215. X            return(found);
  1216. X        }
  1217. X    }
  1218. X}
  1219. Xfind_def(s)
  1220. Xchar *s;
  1221. X{
  1222. X    int mid, cmp, hi,lo;
  1223. X
  1224. X    lo=0;
  1225. X    hi = MAX_DEF-1;
  1226. X    for (; lo<=hi;)
  1227. X    {
  1228. X        mid = (lo+hi)/2;
  1229. X        if ((cmp = strcmp(s, diy[mid].charname)) < 0)
  1230. X            hi = mid-1;
  1231. X        else if (cmp > 0)
  1232. X            lo = mid+1;
  1233. X        else return(diy[mid].chardef);
  1234. X    }
  1235. X    return(EOF);;
  1236. X}
  1237. Xmain()
  1238. X{
  1239. X    FILE *out, *kitfp;
  1240. X    char destname[256];
  1241. X
  1242. X    errno = 0;
  1243. X    if ((kitfp = fopen("diykit.def", "r")) == NULL)
  1244. X    {
  1245. X        fprintf(stderr,"%s: can't open diykit.def, errno %d\n",errno);
  1246. X        exit(1);
  1247. X    }
  1248. X
  1249. X    if (fgets(charset, 126, kitfp) == NULL)
  1250. X    {
  1251. X        fprintf(stderr,"%s: can't read charset info on 1st line, errno %d\n",
  1252. X            PGM,errno);
  1253. X        exit(1);
  1254. X    }
  1255. X    if (font_init("lores.data"))
  1256. X        exit(1);
  1257. X
  1258. X    sprintf(destname, "%s/%s", FAXLIB, FAXLFONT);
  1259. X    if ((out = fopen(destname, "w")) == NULL)
  1260. X    {
  1261. X        fprintf(stderr,"%s: can't create %s, errno %d\n",
  1262. X            PGM,destname,errno);
  1263. X        exit(1);
  1264. X    }
  1265. X    writekit(out,kitfp);
  1266. X    fclose(out);
  1267. X    chmod(destname, 0644);
  1268. X
  1269. X    errno = 0;
  1270. X    rewind(kitfp);
  1271. X    if (fgets(charset, 126, kitfp) == NULL)
  1272. X    {
  1273. X        fprintf(stderr,"%s: can't read charset info on 1st line, errno %d\n",
  1274. X            PGM,errno);
  1275. X        exit(1);
  1276. X    }
  1277. X    if (font_init("hires.data"))
  1278. X        exit(1);
  1279. X
  1280. X    sprintf(destname, "%s/%s", FAXLIB, FAXHFONT);
  1281. X    if ((out = fopen(destname, "w")) == NULL)
  1282. X    {
  1283. X        fprintf(stderr,"%s: can't create %s, errno %d\n",
  1284. X            PGM,destname,errno);
  1285. X        exit(1);
  1286. X    }
  1287. X    writekit(out,kitfp);
  1288. X    fclose(out);
  1289. X    fclose(kitfp);
  1290. X    chmod(destname, 0644);
  1291. X
  1292. X    exit(0);
  1293. X}
  1294. END_OF_FILE
  1295.   if test 5399 -ne `wc -c <'faxhost/faxfonts/diykit.c'`; then
  1296.     echo shar: \"'faxhost/faxfonts/diykit.c'\" unpacked with wrong size!
  1297.   fi
  1298.   # end of 'faxhost/faxfonts/diykit.c'
  1299. fi
  1300. if test -f 'faxhost/sendfax.c' -a "${1}" != "-c" ; then 
  1301.   echo shar: Will not clobber existing file \"'faxhost/sendfax.c'\"
  1302. else
  1303.   echo shar: Extracting \"'faxhost/sendfax.c'\" \(20157 characters\)
  1304.   sed "s/^X//" >'faxhost/sendfax.c' <<'END_OF_FILE'
  1305. X#include <stdio.h>
  1306. X#include <malloc.h>
  1307. X#include <fcntl.h>
  1308. X#include <errno.h>
  1309. X#include <time.h>
  1310. X#include <sys/types.h>
  1311. X#include <dirent.h>
  1312. X#include <unistd.h>
  1313. X
  1314. X#include "../faxconfig.h"
  1315. X
  1316. X/*
  1317. X    sendfax.c
  1318. X
  1319. X    called frequently by cron,
  1320. X    inspect spool area for jobs to do - and get on with it
  1321. X    the actual squirting of data through the serial ports
  1322. X    is done in wiring.c
  1323. X    this file is concerned mainly with reading config info,
  1324. X    collecting and parsing all available x.files and
  1325. X    passing them on to forked copies of sendfax to share
  1326. X    the load
  1327. X
  1328. X    if you have only one faxmodem, all work is done in house
  1329. X    without forking off slave clones
  1330. X
  1331. X    first released version 0.99 [desperado version]
  1332. X    cleaned up Jan 22nd '91,
  1333. X    Copyright (C) 1991, klaus schallhorn, klaus@cnix.uucp
  1334. X
  1335. X    Permission to use, copy, modify, and distribute this software 
  1336. X    and its documentation for any purpose and without fee is hereby 
  1337. X    granted, provided that the above copyright notice appear in 
  1338. X    all copies and that both that copyright notice and this permission 
  1339. X    notice appear in supporting documentation. 
  1340. X
  1341. X    This software is provided "as is" without express or implied warranty.
  1342. X*/
  1343. X
  1344. X#define    COME_BACK    0
  1345. X#define    GO_AWAY        1
  1346. X
  1347. X#define    ALLOWED        1    /* individual permissions, same as cron/at */
  1348. X#define    DENIED        2    /* files: fax.allow, fax.deny */
  1349. X#define    ROOT        3
  1350. X#define    ALL        4
  1351. X
  1352. Xchar    faxrun[256],        /* make a note that's sendfax is running */
  1353. X    tmp[1024],
  1354. X    io[1024];
  1355. X
  1356. X
  1357. Xchar    **faxjobs;        /* list of x.files, jobs to do */
  1358. Xchar    **Denied, **Allowed;    /* fax permissions, same setup as cron */
  1359. Xchar    **CanNow;        /* in case the boss wants to override hours */
  1360. X
  1361. Xstatic    int pid,        /* zip 'em all out to zero */
  1362. X    max_age,        /* days a fax may hover in spool dir */
  1363. X    max_tries,        /* max no of attempts to tx a fax [job] */
  1364. X    faxperms,        /* checking fax.allow && fax.deny */
  1365. X    a_cnt, d_cnt,        /* number of allowed/denied users */
  1366. X    cn_cnt,            /* no of unrestricted users */
  1367. X    dev_cnt,         /* number of devices faxable */
  1368. X    todo;            /* no of fax jobs in queue */
  1369. X
  1370. Xint    blah;            /* chattynes for logging */
  1371. X
  1372. Xstruct    Hours            /* restrict certain area/country codes to cheap hours, */
  1373. X{                /* or local faxes only between midday and noon */
  1374. X    char *dialcode;
  1375. X    char hours[24];
  1376. X} *hour_ptr;
  1377. Xstatic    int h_entries;
  1378. X
  1379. X
  1380. Xstruct config_funcs        /* to read fax.config in any order */
  1381. X{
  1382. X    int    (*funcptr)();        /* function address */
  1383. X    char    *funcname;        /* name used in config file */
  1384. X};
  1385. X
  1386. Xint    device(), incoming(), hours(), maxage(), maxtry(), loglevel();
  1387. Xchar    **Devices,        /* array of device names in /dev */
  1388. X    **Devlocks,        /* array of lock file names */
  1389. X    **Faxtypes,        /* array of fax modem types */
  1390. X    **Wakeup,        /* array of strings to revive modems */
  1391. X    *Dialtyp,        /* array of T's or P's [tone/pulse] */
  1392. X    *Topspeed;        /* array of one byte speed indicators */
  1393. X
  1394. Xstruct config_funcs config_table[] = 
  1395. X{
  1396. X/*    address        funcname    */
  1397. X    { device,    "device"    },
  1398. X    { incoming,    "incoming"    },
  1399. X    { hours,    "hours"        },
  1400. X    { maxage,    "maxage"    },
  1401. X    { maxtry,    "maxtry"    },
  1402. X    { loglevel,    "loglevel"    }
  1403. X};
  1404. X#define    MAX_CONFIG    sizeof(config_table)/sizeof(struct config_funcs)
  1405. X
  1406. Xstruct    FAX fax;
  1407. X
  1408. Xextern    int errno;
  1409. XFILE    *popen();
  1410. X
  1411. X
  1412. Xmain(ac,av)
  1413. Xint ac;
  1414. Xchar *av[];
  1415. X{
  1416. X    char *PGM;
  1417. X
  1418. X    errno = blah = 0;
  1419. X    hour_ptr = NULL;
  1420. X    Topspeed = Dialtyp = NULL;
  1421. X    Allowed = Denied = CanNow = NULL;
  1422. X    Devices = Devlocks = Faxtypes = Wakeup = NULL;
  1423. X
  1424. X    pid = getpid();
  1425. X
  1426. X    if ((PGM = strrchr(av[0], '/')) != NULL)
  1427. X        PGM++;
  1428. X    else PGM = av[0];
  1429. X
  1430. X#ifndef    TESTING
  1431. X    if (fork())    /* errs, parent, or unwanted relatives */
  1432. X        exit(0);
  1433. X    if (setpgrp(0,0))
  1434. X    {
  1435. X        fax_log(ERROR, "sendfax: can't create new prgp\n");
  1436. X        exit(1);
  1437. X    }
  1438. X#endif
  1439. X
  1440. X    if (chdir(FAXSPOOL))    /* quick one, job done */
  1441. X    {
  1442. X        fax_log(ERROR,"sendfax: can't cd to FAXSPOOL\n");
  1443. X        exit(1);
  1444. X    }
  1445. X    if (read_config())
  1446. X        exit(1);
  1447. X
  1448. X    if (!strcmp(PGM, "rcvfax"))
  1449. X        exit(0);    /*rcvfax(); when done */
  1450. X    else            /* sendfax */
  1451. X    {            /* see if sendfax is active, if so, go away */
  1452. X        sprintf(faxrun, "%s/SEND.FAX.RUN",FAXLIB);
  1453. X        if (mklock(faxrun, FALSE, FALSE) < 0)
  1454. X        {
  1455. X            fax_log(5, "sendfax: busy\n");
  1456. X            exit(0); /* last cron job of sendfax still busy */
  1457. X        }
  1458. X        if ((todo = chk_queue()) > 0)
  1459. X        {
  1460. X            if (!blah)
  1461. X                fax_log(0, "sendfax: STARTUP, %d device%c, %d jobs pending\n",
  1462. X                    dev_cnt,(dev_cnt>1)?'s':' ',todo);
  1463. X            else fax_log(9, "sendfax: %d jobs pending\n",todo);
  1464. X            runqueue();
  1465. X        }
  1466. X        fax_log(5, "sendfax: done\n");
  1467. X        unlink(faxrun);
  1468. X    }
  1469. X    exit(0);
  1470. X}
  1471. X
  1472. Xrunqueue()
  1473. X{
  1474. X    int i, j, k, brk, in_use, slot, *kid_pids;
  1475. X    FILE *X;
  1476. X
  1477. X    fax.phone = NULL;
  1478. X
  1479. X    if (dev_cnt > 1)    /* do this only if more than 1 faxmodem */
  1480. X    {
  1481. X        if ((kid_pids = (int *)malloc(dev_cnt * sizeof(int))) == NULL)
  1482. X        {
  1483. X            fax_log(ERROR,"sendfax: can't allocate memory\n");
  1484. X            return;
  1485. X        }
  1486. X        for (i=0; i<dev_cnt; i++)
  1487. X            kid_pids[i] = 0;
  1488. X    }
  1489. X
  1490. X    fax.phone_nos = 0;
  1491. X    for (i=in_use=slot=0; i<todo; i++)
  1492. X    {
  1493. X        fax.tries = fax.uid = fax.now = 
  1494. X            fax.mail = fax.pages = 0;
  1495. X        fax.user[0] = fax.dname[0] = '\0';
  1496. X#ifdef    JOBID
  1497. X        fax.jobid[0] = '\0';
  1498. X#endif
  1499. X        fax.tpos = fax.ppos = fax.spooled = 0L;
  1500. X
  1501. X        if ((X = fopen(faxjobs[i], "r+")) == NULL)
  1502. X        {
  1503. X            fax_log(ERROR,"sendfax: can't open %s\n",faxjobs[i]);
  1504. X            return;
  1505. X        }
  1506. X
  1507. X        if (read_job(X, faxjobs[i]))
  1508. X        {
  1509. X            fax_log(ERROR,"sendfax: can't read %s\n",faxjobs[i]);
  1510. X            return;
  1511. X        }
  1512. X        fax_log(5, "sendfax: %s, %d fax%s, attempt %d, user %s%s\n",
  1513. X            faxjobs[i], fax.phone_nos, (fax.phone_nos>1)?"es":"",
  1514. X            fax.tries, fax.user,
  1515. X            (fax.tries < max_tries)?"":", CANNOT RETRY");
  1516. X
  1517. X        if (fax.tries >= max_tries)
  1518. X        {
  1519. X            fclose(X);
  1520. X            continue;
  1521. X        }
  1522. X
  1523. X        if (chk_perms())
  1524. X        {
  1525. X            fclose(X);
  1526. X            fax_log(ERROR,"sendfax: user %s not permitted to use fax, mailed user, unlinked files\n",fax.user);
  1527. X            rmjob(faxjobs[i],fax.dname,fax.pages);
  1528. X            sprintf(tmp,"echo 'you have no permission to fax [fax admin: %s]' | mail %s",FAXADMIN,fax.user);
  1529. X            system(tmp);
  1530. X            continue;
  1531. X        }
  1532. X
  1533. X/*
  1534. X    can no longer avoid the issue.
  1535. X    if we have just 1 faxmodem, squirt one job now,
  1536. X    if we're sharing the load between several devices, find
  1537. X    an unused one and fork a copy to do the sending. If no
  1538. X    faxmodems avail, wait for one to pop up.
  1539. X
  1540. X    All this assumes uucp is not interfering, this is checked
  1541. X    in "wiring.c", where we just die away [or return in case
  1542. X    of just 1 device] if port cannot be opened
  1543. X*/
  1544. X        if (dev_cnt == 1)
  1545. X        {
  1546. X            sendfax(X, slot, COME_BACK);
  1547. X            continue;
  1548. X        }
  1549. X
  1550. X        for (k=0; k<dev_cnt; k++)
  1551. X            if (!kid_pids[k])
  1552. X            {
  1553. X                slot = k;
  1554. X                break;
  1555. X            }
  1556. X
  1557. X        if ((j = fork()) == ERROR)
  1558. X        {
  1559. X            fax_log(ERROR,"sendfax: can't fork, giving up\n");
  1560. X            return;
  1561. X        }
  1562. X        else if (!j)    /* child */
  1563. X            sendfax(X, slot, GO_AWAY);
  1564. X
  1565. X        fclose(X);    /* still open in child for read/write */
  1566. X        kid_pids[slot] = j;    /* associate kid's pid with dev */
  1567. X
  1568. X        if (++in_use < dev_cnt)
  1569. X            continue;
  1570. X
  1571. X        for (brk=0; !brk;)
  1572. X        {
  1573. X            j = wait((int *)NULL);    /* don't wanna know x status */
  1574. X            for (k=0; k<dev_cnt; k++)
  1575. X                if (j == kid_pids[k])
  1576. X                {        /* make device recycleable */
  1577. X                    kid_pids[k] = 0;
  1578. X                    --in_use;
  1579. X                    brk = TRUE; /* have an unused device */
  1580. X                    break;        /* brk top loop to go on */
  1581. X                }
  1582. X        }
  1583. X    }
  1584. X}
  1585. X
  1586. Xchk_queue()
  1587. X{
  1588. X    DIR *dirp;
  1589. X    struct dirent *dp;
  1590. X    int alloced, entries, i;
  1591. X
  1592. X    if ((dirp = opendir(FAXSPOOL)) == NULL)
  1593. X        return(fax_log(ERROR,"sendfax: can't open directory %s\n",FAXSPOOL));
  1594. X
  1595. X    if ((faxjobs = (char **)malloc(8*sizeof(char *))) == NULL)
  1596. X        return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  1597. X    alloced = 8;
  1598. X    entries = 0;
  1599. X
  1600. X    for (;;)
  1601. X    {
  1602. X        if (entries == alloced)
  1603. X        {
  1604. X            if ((faxjobs = (char **)realloc(faxjobs,
  1605. X                (alloced += 8) * sizeof(char *))) == NULL)
  1606. X                return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  1607. X        }
  1608. X
  1609. X        if ((dp = readdir(dirp)) == NULL)
  1610. X            break;
  1611. X        if (strncmp(dp->d_name, "x.f", 3))
  1612. X            continue;
  1613. X
  1614. X        if ((faxjobs[entries] = malloc(1+strlen(dp->d_name))) == NULL)
  1615. X            return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  1616. X        strcpy(faxjobs[entries++], dp->d_name);
  1617. X    }
  1618. X    closedir(dirp);
  1619. X    i = entries;
  1620. X    while (i < alloced)
  1621. X        faxjobs[i++] = NULL;
  1622. X    return(entries);
  1623. X}
  1624. Xread_config()
  1625. X{
  1626. X    FILE *cfg;
  1627. X    char a[256];
  1628. X    int i;
  1629. X
  1630. X    sprintf(a, "%s/fax.config", FAXLIB);
  1631. X    if ((cfg = fopen(a, "r")) == NULL)
  1632. X    {
  1633. X        fax_log(ERROR,"sendfax: can't open %s/fax.config\n",FAXLIB);
  1634. X        return(ERROR);
  1635. X    }
  1636. X
  1637. X    while (fgets(io, 254, cfg) != NULL)
  1638. X    {
  1639. X        if (io[0] == '#' || (sscanf(io, "%s",a) < 1))
  1640. X            continue;
  1641. X        for (i=0; i<MAX_CONFIG; i++)
  1642. X            if (!strcmp(a,config_table[i].funcname))
  1643. X            {
  1644. X                if ((*config_table[i].funcptr)
  1645. X                    (&io[fstbyte(io,strlen(a))]))
  1646. X                {
  1647. X                    fax_log(ERROR,
  1648. X                        "strange device spec [%s]\n",io);
  1649. X                    return(ERROR);
  1650. X                }
  1651. X                break;
  1652. X            }
  1653. X        if (i == MAX_CONFIG)
  1654. X            fax_log(ERROR,"sendfax: unknown function in config: %s\n",a);
  1655. X    }
  1656. X    fclose(cfg);
  1657. X    if (blah >= 5)    /* alternative STARTUP log is in main with blah == 0 */
  1658. X        fax_log(5, "sendfax: STARTUP, %d device%c\n",dev_cnt,(dev_cnt>1)?'s':' ');
  1659. X    if (get_perms())
  1660. X        return(ERROR);
  1661. X    return(0);
  1662. X}
  1663. Xfstbyte(s,skip)    /* find fst usable item in a config line like: */
  1664. Xchar *s;    /* device /dev/copperwire */
  1665. Xint skip;
  1666. X{
  1667. X    s += skip;
  1668. X    while (*s && isspace(*s))
  1669. X    {
  1670. X        ++skip;
  1671. X        ++s;
  1672. X    }
  1673. X    return(skip);
  1674. X}
  1675. Xnxtint(s)
  1676. Xchar *s;
  1677. X{
  1678. X    char *o;
  1679. X
  1680. X    o = s;
  1681. X    while (*s && (isdigit(*s) || *s == '-'))
  1682. X        ++s;
  1683. X    while (*s && isspace(*s))
  1684. X        ++s;
  1685. X    return((int)(s - o));
  1686. X}
  1687. Xdevice(s)
  1688. Xchar *s;
  1689. X{
  1690. X    static int d_alloced;
  1691. X    char dev[80], devlck[80], faxtyp[80], dial, speed, *sptr, *eptr;
  1692. X
  1693. X    if (sscanf(s,"%s %s %s %c %c",dev,devlck,faxtyp,&dial,&speed) < 5)
  1694. X        return(ERROR);
  1695. X
  1696. X    if (!d_alloced)
  1697. X    {
  1698. X        if (((Devices = (char **)malloc(4*sizeof(char *))) == NULL)
  1699. X            || ((Devlocks = (char **)malloc(4*sizeof(char *))) == NULL)
  1700. X            || ((Faxtypes = (char **)malloc(4*sizeof(char *))) == NULL)
  1701. X            || ((Wakeup = (char **)malloc(4*sizeof(char *))) == NULL)
  1702. X            || ((Dialtyp = (char *)malloc(4)) == NULL)
  1703. X            || ((Topspeed = (char *)malloc(4)) == NULL))
  1704. X            return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  1705. X        d_alloced = 4;
  1706. X    }
  1707. X    else if (d_alloced == dev_cnt)
  1708. X    {
  1709. X        d_alloced += 4;
  1710. X        if (((Devices = (char **)realloc(Devices,
  1711. X            d_alloced * sizeof(char *))) == NULL)
  1712. X            || ((Devlocks = (char **)realloc(Devlocks,
  1713. X            d_alloced * sizeof(char *))) == NULL)
  1714. X            || ((Faxtypes = (char **)realloc(Faxtypes,
  1715. X            d_alloced * sizeof(char *))) == NULL)
  1716. X            || ((Wakeup = (char **)realloc(Wakeup,
  1717. X            d_alloced * sizeof(char *))) == NULL)
  1718. X            || ((Dialtyp = (char *)realloc(Dialtyp,
  1719. X            d_alloced)) == NULL)
  1720. X            || ((Topspeed = (char *)realloc(Topspeed,
  1721. X            d_alloced)) == NULL))
  1722. X            return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  1723. X    }
  1724. X    if (((Devices[dev_cnt] = malloc(1+strlen(dev))) == NULL)
  1725. X        || ((Devlocks[dev_cnt] = malloc(1+strlen(devlck))) == NULL)
  1726. X        || ((Faxtypes[dev_cnt] = malloc(1+strlen(faxtyp))) == NULL))
  1727. X        return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  1728. X    strcpy(Devices[dev_cnt],  dev);
  1729. X    strcpy(Devlocks[dev_cnt], devlck);
  1730. X    strcpy(Faxtypes[dev_cnt], faxtyp);
  1731. X    Dialtyp[dev_cnt] = dial;
  1732. X    Topspeed[dev_cnt] = speed;
  1733. X
  1734. X    if (((sptr = strchr(s, '"')) != NULL)
  1735. X        && ((eptr = strrchr(s, '"')) != NULL)
  1736. X        && (eptr > sptr))
  1737. X    {
  1738. X        *eptr = '\0';
  1739. X        ++sptr;
  1740. X        if ((Wakeup[dev_cnt] = malloc(1+(int)(eptr-sptr))) == NULL)
  1741. X            return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  1742. X        strcpy(Wakeup[dev_cnt], sptr);
  1743. X    }
  1744. X    else Wakeup[dev_cnt] = NULL;
  1745. X
  1746. X    ++dev_cnt;
  1747. X    return(0);
  1748. X}
  1749. Xincoming(s)
  1750. Xchar *s;
  1751. X{
  1752. X/*    haven't had time to do this
  1753. X    if (sscanf(s,"%s",Incoming) < 1)
  1754. X*/
  1755. X        return(ERROR);
  1756. X}
  1757. Xmaxtry(s)
  1758. Xchar *s;
  1759. X{
  1760. X    if (sscanf(s,"%d",&max_tries) < 1)
  1761. X        return(ERROR);
  1762. X    return(0);
  1763. X}
  1764. Xloglevel(s)
  1765. Xchar *s;
  1766. X{
  1767. X    if (sscanf(s,"%d",&blah) < 1)
  1768. X        return(ERROR);
  1769. X    return(0);
  1770. X}
  1771. Xmaxage(s)
  1772. Xchar *s;
  1773. X{
  1774. X    if (sscanf(s,"%d",&max_age) < 1)
  1775. X        return(ERROR);
  1776. X    return(0);
  1777. X}
  1778. Xhours(s)
  1779. Xchar *s;
  1780. X{
  1781. X    static int h_alloced;
  1782. X    int i, lasth;
  1783. X    char *p;
  1784. X
  1785. X    if (sscanf(s,"%s",tmp) < 1)    /* expect dial code */
  1786. X        return(ERROR);
  1787. X    i = strlen(tmp);
  1788. X    s += fstbyte(s, i);            /* skip him */
  1789. X
  1790. X    if (!h_entries)
  1791. X    {
  1792. X        if ((hour_ptr = (struct Hours *)malloc(
  1793. X                (h_alloced += 8) * sizeof(struct Hours))) == NULL)
  1794. X            return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  1795. X    }
  1796. X    else if (h_alloced == h_entries)
  1797. X    {
  1798. X        if ((hour_ptr = (struct Hours *)realloc(hour_ptr,
  1799. X                (h_alloced += 8) * sizeof(struct Hours))) == NULL)
  1800. X            return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  1801. X    }
  1802. X    if ((hour_ptr[h_entries].dialcode = malloc(1+i)) == NULL)
  1803. X        return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  1804. X    strcpy(hour_ptr[h_entries].dialcode, tmp);
  1805. X
  1806. X    p = hour_ptr[h_entries].hours;
  1807. X    for (i=0; i<24; i++)
  1808. X        *p++ = '\0';
  1809. X
  1810. X    lasth = -1;
  1811. X    p = hour_ptr[h_entries].hours;
  1812. X
  1813. X    while (*s && *s != '#')
  1814. X    {
  1815. X        if (isdigit(*s))
  1816. X        {
  1817. X            if ((i = atoi(s)) < 0 || i > 23)
  1818. X                return(ERROR);
  1819. X            p[i] = '\1';
  1820. X            if (lasth > -1)
  1821. X            {
  1822. X                if (lasth < i)
  1823. X                {
  1824. X                    while (lasth < i)
  1825. X                        p[lasth++] = '\1';
  1826. X                }
  1827. X                else
  1828. X                {
  1829. X                    while (lasth < 24)
  1830. X                        p[lasth++] = '\1';
  1831. X                    lasth = 0;
  1832. X                    while (lasth < i)
  1833. X                        p[lasth++] = '\1';
  1834. X                }
  1835. X                lasth = -1;
  1836. X            }
  1837. X            s += nxtint(s);
  1838. X        }
  1839. X        else if (*s == '-')
  1840. X        {
  1841. X            lasth = i;
  1842. X            s += nxtint(s);
  1843. X        }
  1844. X    }
  1845. X    ++h_entries;
  1846. X    return(0);
  1847. X}
  1848. X#define    MATCHCMASK    0377
  1849. X#define    MATCHQUOTE    0200
  1850. X#define    MATCHQMASK    (MATCHCMASK&~MATCHQUOTE)
  1851. X#define    MATCHNOT    '^'
  1852. X
  1853. Xstatic    char    *cclass();
  1854. X
  1855. Xmatch(s, p)
  1856. Xchar *s, *p;
  1857. X{
  1858. X    int sc, pc;
  1859. X
  1860. X    while ((pc = *p++ & MATCHCMASK) != '\0')
  1861. X    {
  1862. X        sc = *s++ & MATCHQMASK;
  1863. X        switch (pc)
  1864. X        {
  1865. X        case '[':
  1866. X            if ((p = cclass(p, sc)) == NULL)
  1867. X                return(0);
  1868. X            break;
  1869. X        case '?':
  1870. X            if (sc == 0)
  1871. X                return(0);
  1872. X            break;
  1873. X        case '*':
  1874. X            s--;
  1875. X            do
  1876. X            {
  1877. X                if (*p == '\0' || match(s, p))
  1878. X                    return(1);
  1879. X            } while (*s++ != '\0');
  1880. X            return(0);
  1881. X        default:
  1882. X            if (sc != (pc & ~MATCHQUOTE))
  1883. X                return(0);
  1884. X        }
  1885. X    }
  1886. X    return(*s == 0);
  1887. X}
  1888. X
  1889. Xstatic char *cclass(p, sub)
  1890. Xchar *p;
  1891. Xint sub;
  1892. X{
  1893. X    int c, d, not, found;
  1894. X
  1895. X    if ((not = *p == MATCHNOT) != 0)
  1896. X        p++;
  1897. X    found = not;
  1898. X
  1899. X    do
  1900. X    {
  1901. X        if (*p == '\0')
  1902. X            return(NULL);
  1903. X        c = *p & MATCHCMASK;
  1904. X        if (p[1] == '-' && p[2] != ']')
  1905. X        {
  1906. X            d = p[2] & MATCHCMASK;
  1907. X            p++;
  1908. X        }
  1909. X        else d = c;
  1910. X
  1911. X        if (c == sub || c <= sub && sub <= d)
  1912. X            found = !not;
  1913. X    } while (*++p != ']');
  1914. X
  1915. X    return(found ? (p+1) : NULL);
  1916. X}
  1917. Xget_perms()
  1918. X{
  1919. X    FILE *fp;
  1920. X    int a_alloced, d_alloced, len;
  1921. X
  1922. X    a_alloced = d_alloced = 0;
  1923. X    sprintf(tmp, "%s/fax.allow", FAXLIB);
  1924. X    if ((fp = fopen(tmp, "r")) != NULL)
  1925. X    {
  1926. X        if ((Allowed = (char **)malloc(8*sizeof(char *))) == NULL)
  1927. X            return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  1928. X        a_alloced = 8;
  1929. X
  1930. X        for (;;)
  1931. X        {
  1932. X            if (a_cnt == a_alloced)
  1933. X            {
  1934. X                if ((Allowed = (char **)realloc(Allowed,
  1935. X                    (a_alloced += 8) * sizeof(char *))) == NULL)
  1936. X                    return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  1937. X            }
  1938. X
  1939. X            if (fgets(tmp, 128, fp) == NULL)
  1940. X                break;
  1941. X            if ((len = strlen(tmp)) == 0)
  1942. X                break;
  1943. X
  1944. X            tmp[--len] = '\0';
  1945. X            if (!len)
  1946. X                continue;
  1947. X            if ((Allowed[a_cnt] = malloc(1+len)) == NULL)
  1948. X                return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  1949. X            strcpy(Allowed[a_cnt++], tmp);
  1950. X        }
  1951. X        if (a_cnt)
  1952. X            faxperms = ALLOWED;
  1953. X        fclose(fp);
  1954. X    }
  1955. X    else
  1956. X    {
  1957. X        sprintf(tmp, "%s/fax.deny", FAXLIB);
  1958. X        if ((fp = fopen(tmp, "r")) != NULL)
  1959. X        {
  1960. X            if ((Denied = (char **)malloc(8*sizeof(char *))) == NULL)
  1961. X                return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  1962. X            d_alloced = 8;
  1963. X
  1964. X            for (;;)
  1965. X            {
  1966. X                if (d_cnt == d_alloced)
  1967. X                {
  1968. X                    if ((Denied = (char **)realloc(Denied,
  1969. X                        (d_alloced += 8) * sizeof(char *))) == NULL)
  1970. X                        return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  1971. X                }
  1972. X
  1973. X                if (fgets(tmp, 128, fp) == NULL)
  1974. X                    break;
  1975. X                if ((len = strlen(tmp)) == 0)
  1976. X                    break;
  1977. X
  1978. X                tmp[--len] = '\0';
  1979. X                if (!len)
  1980. X                    continue;
  1981. X                if ((Denied[d_cnt] = malloc(1+len)) == NULL)
  1982. X                    return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  1983. X                strcpy(Denied[d_cnt++], tmp);
  1984. X            }
  1985. X            if (d_cnt)
  1986. X                faxperms = DENIED;
  1987. X            else faxperms = ALL;
  1988. X            fclose(fp);
  1989. X        }
  1990. X    }
  1991. X    if (!faxperms)
  1992. X        faxperms = ROOT;
  1993. X    return(get_boss_perms());
  1994. X}
  1995. Xget_boss_perms()
  1996. X{
  1997. X    FILE *fp;
  1998. X    int cn_alloced, len;
  1999. X
  2000. X    cn_alloced = 0;
  2001. X    sprintf(tmp, "%s/fax.always", FAXLIB);
  2002. X    if ((fp = fopen(tmp, "r")) != NULL)
  2003. X    {
  2004. X        if ((CanNow = (char **)malloc(8*sizeof(char *))) == NULL)
  2005. X            return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  2006. X        cn_alloced = 8;
  2007. X
  2008. X        for (;;)
  2009. X        {
  2010. X            if (cn_cnt == cn_alloced)
  2011. X            {
  2012. X                if ((CanNow = (char **)realloc(CanNow,
  2013. X                    (cn_alloced += 8) * sizeof(char *))) == NULL)
  2014. X                    return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  2015. X            }
  2016. X
  2017. X            if (fgets(tmp, 128, fp) == NULL)
  2018. X                break;
  2019. X            if ((len = strlen(tmp)) == 0)
  2020. X                break;
  2021. X            tmp[--len] = '\0';
  2022. X            if (!len)
  2023. X                continue;
  2024. X            if ((CanNow[cn_cnt] = malloc(1+len)) == NULL)
  2025. X                return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  2026. X            strcpy(CanNow[cn_cnt++], tmp);
  2027. X        }
  2028. X        fclose(fp);
  2029. X    }
  2030. X    fax_log(3, "sendfax: faxperms %d, allowed %d, denied %d, always %d\n",
  2031. X        faxperms, a_cnt, d_cnt, cn_cnt);
  2032. X    return(0);
  2033. X}
  2034. Xread_job(fp, xn)
  2035. XFILE *fp;
  2036. Xchar *xn;
  2037. X{
  2038. X    int i;
  2039. X
  2040. X    if (fax.phone_nos)    /* has been called before, clean up */
  2041. X    {
  2042. X        for (i=0; i<fax.phone_nos; i++)
  2043. X            if (fax.phone[i] != NULL)
  2044. X                free(fax.phone[i]);
  2045. X        free(fax.phone);
  2046. X        fax.phone = NULL;
  2047. X        fax.phone_nos = 0;
  2048. X    }
  2049. X
  2050. X/*
  2051. X    these are read in the order they're written
  2052. X    by the spooler, not they way the structure is designed
  2053. X*/
  2054. X    if (getint(fp,&fax.spooled))    /* spool timestamp */
  2055. X        return(ERROR);
  2056. X    fax.tpos = ftell(fp);    /* might need to rewrite no of attempts */
  2057. X    if (getint(fp,&fax.tries)
  2058. X        || getstring(fp,fax.user) || getint(fp,&fax.uid)
  2059. X        || getint(fp,&fax.now) || getint(fp,&fax.mail)
  2060. X        || getint(fp,&fax.type)
  2061. X        || getint(fp,&fax.hires)
  2062. X        || getstring(fp,tmp)    /* font, don't need to know this */
  2063. X        || getstring(fp,tmp))    /* retfax, don't need to know either */
  2064. X        return(ERROR);
  2065. X    fax.ppos = ftell(fp);        /* if we succeed on partial phone list */
  2066. X    if ((fax.phone_nos = getphone(fp)) <= 0) /* rewrite those not yet done */
  2067. X        return(ERROR);
  2068. X    if (getstring(fp,fax.dname))
  2069. X        return(ERROR);
  2070. X    strcpy(fax.xname, xn);
  2071. X    if (getint(fp,&fax.pages))
  2072. X        return(ERROR);
  2073. X#ifdef    JOBID
  2074. X    if (getstring(fp,fax.jobid))
  2075. X        return(ERROR);
  2076. X#endif
  2077. X    return(0);
  2078. X}
  2079. Xgetstring(fp,s)
  2080. XFILE *fp;
  2081. Xchar *s;
  2082. X{
  2083. X    char buf[80];
  2084. X
  2085. X    if (fgets(io, 80, fp) == NULL)
  2086. X        return(ERROR);
  2087. X    if (sscanf(io, "%s %s",buf,s) != 2)
  2088. X        return(ERROR);
  2089. X    return(0);
  2090. X}
  2091. Xgetint(fp,n)
  2092. XFILE *fp;
  2093. Xint *n;
  2094. X{
  2095. X    long l;
  2096. X
  2097. X    if (fgets(io, 80, fp) == NULL)
  2098. X        return(ERROR);
  2099. X    if (sscanf(io, "%s %ld",tmp,&l) != 2)
  2100. X        return(ERROR);
  2101. X    *n = l;
  2102. X    return(0);
  2103. X}
  2104. Xgetphone(fp)
  2105. XFILE *fp;
  2106. X{
  2107. X    int i, p_entries=0, p_alloced=0;
  2108. X    char phone[80];
  2109. X    long oldpos;
  2110. X
  2111. X    if ((fax.phone = (char **)malloc(8*sizeof(char *))) == NULL)
  2112. X        return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  2113. X    p_alloced = 8;
  2114. X    p_entries = 0;
  2115. X
  2116. X    for (;;)
  2117. X    {
  2118. X        oldpos = ftell(fp);
  2119. X
  2120. X        if (p_entries == p_alloced)
  2121. X        {
  2122. X            if ((fax.phone = (char **)realloc(fax.phone,
  2123. X                (p_alloced += 8) * sizeof(char *))) == NULL)
  2124. X                return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  2125. X        }
  2126. X
  2127. X        if (fgets(io, 80, fp) == NULL)
  2128. X            return(ERROR);
  2129. X        if (io[0] == '#')
  2130. X            continue;
  2131. X        if (!strncmp(io, "data", 4))
  2132. X        {
  2133. X            fseek(fp, oldpos, 0);
  2134. X            break;
  2135. X        }
  2136. X        if (sscanf(io, "%s %s",tmp,phone) < 2)
  2137. X            return(ERROR);
  2138. X
  2139. X        if ((fax.phone[p_entries] = malloc(1+strlen(phone))) == NULL)
  2140. X            return(fax_log(ERROR,"sendfax: can't allocate memory\n"));
  2141. X        strcpy(fax.phone[p_entries++], phone);
  2142. X    }
  2143. X    for (i=p_entries; i<p_alloced; i++)
  2144. X        fax.phone[i] = NULL;
  2145. X    return(p_entries);
  2146. X}
  2147. Xchk_perms()
  2148. X{
  2149. X    int i;
  2150. X
  2151. X    if (faxperms == ALL)
  2152. X        return(FALSE);
  2153. X    else if ((faxperms == ROOT) && (!fax.uid))
  2154. X        return(FALSE);
  2155. X    else if (faxperms == ALLOWED)
  2156. X    {
  2157. X        for (i=0; i<a_cnt; i++)
  2158. X            if (!strcmp(fax.user, Allowed[i]))
  2159. X                return(FALSE);
  2160. X    }
  2161. X    else if (faxperms == DENIED)
  2162. X    {
  2163. X        for (i=0; i<d_cnt; i++)
  2164. X            if (!strcmp(fax.user, Denied[i]))
  2165. X                return(ERROR);
  2166. X        return(FALSE);
  2167. X    }
  2168. X    return(ERROR);
  2169. X}
  2170. Xnot_now(uid,now,phone)
  2171. Xint uid, now;
  2172. Xchar *phone;
  2173. X{
  2174. X    int i;
  2175. X    time_t cur;
  2176. X    struct tm *tml, *localtime();
  2177. X
  2178. X    if (fax.now)
  2179. X    {
  2180. X        if (!fax.uid) /* if root can edit fax.config it can fax now */
  2181. X            return(FALSE);
  2182. X        for (i=0; i<cn_cnt; i++)
  2183. X            if (!strcmp(fax.user, CanNow[i]))
  2184. X                return(FALSE);
  2185. X    }
  2186. X    
  2187. X    for (i=0; i<h_entries; i++)    /* check area/cty codes for restrictions */
  2188. X        if (match(phone, hour_ptr[i].dialcode))
  2189. X        {
  2190. X            (void)time(&cur);
  2191. X            tml = localtime(&cur);    /* if not allowed at this hour */
  2192. X            if (!hour_ptr[i].hours[tml->tm_hour])
  2193. X                return(ERROR);
  2194. X            return(FALSE);
  2195. X        }
  2196. X    return(FALSE);        /* no restrictions on this phone number */
  2197. X}
  2198. Xrmjob(xname,dname,pages)
  2199. Xchar *xname,*dname;
  2200. Xint pages;
  2201. X{
  2202. X    char buf[256], *d;
  2203. X    int i;
  2204. X
  2205. X    unlink(xname);
  2206. X    for (i=0; i<pages; i++)
  2207. X    {
  2208. X        sprintf(buf,"%s.g3.%d",dname,i);
  2209. X        unlink(buf);
  2210. X    }
  2211. X}
  2212. END_OF_FILE
  2213.   if test 20157 -ne `wc -c <'faxhost/sendfax.c'`; then
  2214.     echo shar: \"'faxhost/sendfax.c'\" unpacked with wrong size!
  2215.   fi
  2216.   # end of 'faxhost/sendfax.c'
  2217. fi
  2218. echo shar: End of archive 2 \(of 5\).
  2219. cp /dev/null ark2isdone
  2220. MISSING=""
  2221. for I in 1 2 3 4 5 ; do
  2222.     if test ! -f ark${I}isdone ; then
  2223.     MISSING="${MISSING} ${I}"
  2224.     fi
  2225. done
  2226. if test "${MISSING}" = "" ; then
  2227.     echo You have unpacked all 5 archives.
  2228.     rm -f ark[1-9]isdone
  2229. else
  2230.     echo You still must unpack the following archives:
  2231.     echo "        " ${MISSING}
  2232. fi
  2233. exit 0
  2234. exit 0 # Just in case...
  2235.